package com.ccBatis.sqlSession;

import com.ccBatis.exexutor.Executor;
import com.ccBatis.pojo.Configuration;
import com.ccBatis.pojo.MappedStatement;

import java.lang.reflect.*;
import java.util.List;

public class DefaultSqlSession implements SqlSession {

    private Configuration configuration;

    private Executor executor;

    public DefaultSqlSession(Configuration configuration, Executor executor) {
        this.configuration = configuration;
        this.executor = executor;
    }

    @Override
    public <E> List<E> selectList(String statementId,Object param) {
        MappedStatement mappedStatement = configuration.getMappedStatementMap().get(statementId);
        // 将查询操作委派给执行器
        return executor.query(configuration,mappedStatement,param);
    }

    @Override
    public <E> E selectOne(String statementId,Object param) {
        List<Object> list = this.selectList(statementId, param);
        if(list.size()==1){
            return (E)list.get(0);
        }else if(list.size()>1){
            throw new RuntimeException("查询出多条结果");
        }
        return null;
    }

    @Override
    public void close() {
        executor.close();
    }

    @Override
    public <E> E getMapper(Class<?> mapperClass) {

        Object o = Proxy.newProxyInstance(DefaultSqlSession.class.getClassLoader(), new Class[]{mapperClass}, new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

                // 参数准备 statementId param
                // name:findAll
                String methodName = method.getName();
                // com.test.dao.UserDao
                String className = method.getDeclaringClass().getName();
                String statementId = className+"."+methodName;

                MappedStatement mappedStatement = configuration.getMappedStatementMap().get(statementId);

                String sqlCommentType = mappedStatement.getSqlCommentType();

                switch (sqlCommentType){
                    case "select":
                        Type genericReturnType = method.getGenericReturnType();
                        // 是否实现了 泛型类型参数话
                        if(genericReturnType instanceof ParameterizedType){
                            if(args!=null){
                                return  selectList(statementId,args[0]);
                            }
                           return selectList(statementId,null);
                        }else{
                            return selectOne(statementId,args[0]);
                        }
                    case "insert":
                        break;
                    case "update":
                        break;
                    case "delete":
                        break;
                    default:
                         break;
                }
                return null;
            }
        });
        return (E)o;
    }
}
